package org.dragonnova.meetingapp.app.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ztspeech.AZTClient;

import org.dragonnova.meetingapp.R;
import org.dragonnova.meetingapp.app.adapter.ChatListAdapter;
import org.dragonnova.meetingapp.core.manager.UdpManager;
import org.dragonnova.meetingapp.model.bean.VoiceInfo;
import org.dragonnova.meetingapp.app.service.TranslationService;
import org.dragonnova.meetingapp.app.service.WIFIServiceTest;
import org.dragonnova.meetingapp.utils.Constants;
import org.dragonnova.meetingapp.utils.ContentResolverUtil;
import org.dragonnova.meetingapp.utils.LogUtil;
import org.dragonnova.meetingapp.utils.ToastUtil;
import org.dragonnova.meetingapp.utils.UIHelper;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class RecordActivity extends AppCompatActivity implements ServiceConnection, View.OnClickListener {

    private ListView mListView;
    private ChatListAdapter mAdapter;

    //翻译服务
    private TranslationService.MyBinder transBinder;
    private TranslationService transService;
    //wifi服务
    private WIFIServiceTest wifiService;
    private WIFIServiceTest.WifiBinder wifiBinder;

    private ArrayList<VoiceInfo> chatList = new ArrayList<>();//存放聊天记录的list
    private TextView record_tb_tv_title;
    private TextView record_tv_recognizing;
    //由于keyup的时候系统还没有返回值，所以需要判断是否已经松开
    private boolean isKeyUp = true;

    private boolean isCH2EN;
    private ImageView record_bt_speech;

    private StateImp mState;

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int what = msg.what;
            switch (what) {
                case 100:

                    break;
                case 101:
                    if (!isKeyUp) {
                        if (wifiBinder != null) {
                            wifiBinder.requestVoicePersist();
                        }
                        this.sendEmptyMessageDelayed(101, 300);
                    }
                    break;
            }
        }
    };
    private LinearLayout record_ll_language;
    private RelativeLayout record_rl_language_cancel;
    private FrameLayout record_fl_cover;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record);

        Intent intent = getIntent();
        if (intent != null) {
            int action = intent.getIntExtra(Constants.ACTIVITY_INTENT_ACTION, -1);
            if (action >= 0) {
                switch (action) {
                    case Constants.ACTIVITY_ACTION_CREATOR:
                        mState = new CreatorState();
                        break;
                    case Constants.ACTIVITY_ACTION_PARTICIPANT:
                        mState = new ParticipantState();
                        break;
                    default:
                        throw new RuntimeException("MeetingGuideActivity received an action that not defined");
                }
            } else {
                throw new RuntimeException("MeetingGuideActivity received an action that not defined");
            }
        }

        initView();
        initData();
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (wifiBinder != null) {
            showHistory();
            String title = wifiBinder.getMeetingInfo().getName();
            if (!TextUtils.isEmpty(title)) {
                record_tb_tv_title.setText(title);
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        wifiBinder.stopGroup();
        unbindService();
        unRegisterBroadcastReceiver();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_record, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            /*case R.id.action_invite_participant:
                break;*/
            case R.id.action_check_participants:
                mState.getParticipants();
                break;
            case R.id.action_set_lauguage:
                mState.setLanguage();
                break;
            case R.id.action_set_meeting:
                mState.setMeeting();
                break;
            case R.id.action_collect_meeting:
                if (wifiBinder != null) {
                    ContentResolverUtil contentResolverUtil = new ContentResolverUtil(this);
                    contentResolverUtil.collectMeeting(wifiBinder.getMeetingInfo());
                    ToastUtil.showTip("收藏成功");
                }
                break;
            case R.id.action_close_meeting:
                mState.closeMeeting();
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected boolean onPrepareOptionsPanel(View view, Menu menu) {
        if (menu != null) {
            if (menu.getClass() == MenuBuilder.class) {
                try {
                    Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (Exception e) {
                    //Out.print(getClass().getSimpleName() + "onMenuOpened...unable to set icons for overflow menu" + e);
                }
            }
        }
        return super.onPrepareOptionsPanel(view, menu);
    }

    public void initView() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) getSupportActionBar().setDisplayShowTitleEnabled(false);

        mListView = (ListView) this.findViewById(R.id.record_lv);
        record_bt_speech = (ImageView) this.findViewById(R.id.record_iv_speech);
        record_tb_tv_title = (TextView) findViewById(R.id.history_tb_tv_title);
        record_tv_recognizing = (TextView) findViewById(R.id.record_tv_recognizing);
        record_ll_language = (LinearLayout) findViewById(R.id.record_ll_language);
        record_rl_language_cancel = (RelativeLayout) findViewById(R.id.record_rl_language_cancel);
        record_fl_cover = (FrameLayout) findViewById(R.id.record_fl_cover);
        TextView record_tv_language_cancel = (TextView) findViewById(R.id.record_tv_language_cancel);
        TextView record_tv_language_ch = (TextView) findViewById(R.id.record_tv_language_ch);
        TextView record_tv_language_en = (TextView) findViewById(R.id.record_tv_language_en);

        record_rl_language_cancel.setVisibility(View.GONE);
        record_ll_language.setVisibility(View.GONE);
        record_fl_cover.setVisibility(View.GONE);

        record_tv_language_cancel.setOnClickListener(this);
        record_tv_language_ch.setOnClickListener(this);
        record_tv_language_en.setOnClickListener(this);


        if (record_bt_speech != null) {
            record_bt_speech.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            if (wifiBinder != null) {
                                wifiBinder.requestVoiceStart();
                            }
                            mHandler.sendEmptyMessageDelayed(101, 300);
                            isKeyUp = false;
                            break;
                        case MotionEvent.ACTION_UP:
                            isKeyUp = true;
                            if (wifiBinder != null) {
                                wifiBinder.requestVoiceStop();
                            }
                            if (transBinder != null) {
                                transBinder.stopContinuousRecord();
                            }
                            mHandler.sendEmptyMessageDelayed(100, 300);
                            record_tv_recognizing.setVisibility(View.GONE);
                            break;
                    }
                    return true;
                }
            });
        }
    }


    public void initData() {
        //初始化聊天记录
        mAdapter = new ChatListAdapter(RecordActivity.this, chatList);
        mListView.setAdapter(mAdapter);

        //初始化语音参数
        isCH2EN = true;

        //初始化翻译的地址
        String orgServerPath = getString(R.string.server_addr);
        String hzServerPath = getString(R.string.server_addr_hangzhou);
        String path = hzServerPath + ":" + getResources().getInteger(R.integer.server_port)
                + "/" + getString(R.string.servlet_path);
        AZTClient.setServerPath(path);

        bindService();
        registerBroadcastReceiver();
    }

    /**
     * 绑定服务
     */
    private void bindService() {
        //启动服务
        Intent wifiIntent = new Intent(RecordActivity.this, WIFIServiceTest.class);
        bindService(wifiIntent, this, BIND_AUTO_CREATE);

        Intent intent = new Intent(this, TranslationService.class);
        bindService(intent, this, Context.BIND_AUTO_CREATE);
    }

    /**
     * 解除服务绑定
     */
    private void unbindService() {
        unbindService(this);
        LogUtil.eee("unbind service successfully");
    }

    /**
     * 注册广播
     */
    private void registerBroadcastReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Constants.WIFI_BORADCAST_ACTION);
        filter.addAction(Constants.TRANS_BORADCAST_ACTION);
        registerReceiver(WifiReceiver, filter);
    }

    private void unRegisterBroadcastReceiver() {
        unregisterReceiver(WifiReceiver);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        if (service instanceof WIFIServiceTest.WifiBinder) {
            wifiBinder = (WIFIServiceTest.WifiBinder) service;
            wifiService = ((WIFIServiceTest.WifiBinder) service).getService();
            LogUtil.eee(String.valueOf(wifiService.hashCode()));

            String title = wifiBinder.getMeetingInfo().getName();
            if (!TextUtils.isEmpty(title)) {
                record_tb_tv_title.setText(title);
            }
            showHistory();
        } else if (service instanceof TranslationService.MyBinder) {
            transBinder = (TranslationService.MyBinder) service;
            transService = ((TranslationService.MyBinder) service).getService();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        LogUtil.eee(name.getClassName() + " has disconnected");
    }

    /**
     * 开始录音
     */
    private void startRecord() {
        stopAll();
        if (transBinder != null) {
            if (ContextCompat.checkSelfPermission(RecordActivity.this,
                    Manifest.permission.RECORD_AUDIO)
                    != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(RecordActivity.this,
                        Manifest.permission.READ_CONTACTS)) {

                    // Show an expanation to the user *asynchronously* -- don't block
                    // this thread waiting for the user's response! After the user
                    // sees the explanation, try again to request the permission.
                    ActivityCompat.requestPermissions(RecordActivity.this,
                            new String[]{Manifest.permission.RECORD_AUDIO},
                            MY_PERMISSIONS_REQUEST_RECORD_AUDIO);

                } else {
                    transBinder.startRecord(isCH2EN);
                }
            }
        }
    }

    private static final int MY_PERMISSIONS_REQUEST_RECORD_AUDIO = 1;

    /**
     * 开始连续录音
     */
    private void startContinuousRecord() {
        stopAll();
        if (transBinder != null) {
            if (ContextCompat.checkSelfPermission(RecordActivity.this,
                    Manifest.permission.RECORD_AUDIO)
                    != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(RecordActivity.this,
                        new String[]{Manifest.permission.RECORD_AUDIO},
                        MY_PERMISSIONS_REQUEST_RECORD_AUDIO);
            } else {
                transBinder.startContinuousRecord(isCH2EN);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if (requestCode == MY_PERMISSIONS_REQUEST_RECORD_AUDIO) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                transBinder.startContinuousRecord(isCH2EN);
            } else {
                // Permission Denied
                ToastUtil.showTip("授权失败");
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }


    /**
     * 结束录音
     */

    private void stopRecord() {
        if (transBinder != null) transBinder.stopRecord();
    }

    /**
     * 结束录音,且不保存，不识别
     */
    private void cancelRecord() {
        if (transBinder != null) transBinder.cancelRecord();
    }

    /**
     * 停止录音,播放,停止合成及消息队列
     */
    private void stopAll() {
        if (transBinder != null) transBinder.stopAll();
    }

    /**
     * service发送的广播
     */
    private BroadcastReceiver WifiReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Constants.TRANS_BORADCAST_ACTION)) {
                String option = intent.getStringExtra(Constants.BORADCAST_INTENT_OPTION);
                switch (option) {
                    case TranslationService.EXTRA_TEMP_RESULT_CHANGED:
                        break;
                    case TranslationService.EXTRA_TRANSLATED:
                        //VoiceInfo voiceInfo = (VoiceInfo) intent.getSerializableExtra("voiceInfo");
                        break;
                    case TranslationService.EXTRA_NO_RESULT:
                        break;
                    case TranslationService.EXTRA_RECOGNIZE_FINISHED:
                        break;
                    case TranslationService.EXTRA_RECOGNIZED_RESULT:
                        VoiceInfo voiceInfo = (VoiceInfo) intent.getSerializableExtra("voiceInfo");
                        LogUtil.eee(voiceInfo.toString());
                        sendVoice(voiceInfo);
                        break;
                }
            } else if (intent.getAction().equals(Constants.WIFI_BORADCAST_ACTION)) {
                String option = intent.getStringExtra(Constants.BORADCAST_INTENT_OPTION);
                switch (option) {
                    case UdpManager.KEY_GROUP_CONNECTED_STATUS:
                        LogUtil.iii("WIFI已连接");
                        break;
                    case UdpManager.KEY_GROUP_CONNECTING_STATUS:
                        LogUtil.iii("WIFI连接中");
                        break;
                    case UdpManager.KEY_GROUP_DISCONNECT_STATUS:
                        LogUtil.iii("WIFI未连接");
                        break;
                    case UdpManager.KEY_HANDLER_ORG_VOICE_DATA:
                        LogUtil.iii("合成服务端返回结果");
                        VoiceInfo voiceInfo = (VoiceInfo) intent.getSerializableExtra(UdpManager.INTENT_TRANSFER_VOICE_DATA);
                        chatList.add(voiceInfo);
                        mAdapter.notifyDataSetChanged();
                        showHistory();
                        break;
                    case UdpManager.KEY_HANDLER_ORG_VOICE_TEXT_ERROR:
                        LogUtil.iii("服务端无返回结果");
                        break;
                    case UdpManager.KEY_VOICE_RESPONSE_PERMIT:
                        LogUtil.iii("请进行语音输入");
                        //ToastUtil.showTip("请说话");
                        if (!isKeyUp) {
                            startContinuousRecord();
                            record_tv_recognizing.setVisibility(View.VISIBLE);
                        } else {
                            wifiBinder.requestVoiceStop();
                        }
                        break;
                    case UdpManager.KEY_VOICE_RESPONSE_PREVENT:
                        LogUtil.iii("服务端阻止了语音输入");
                        ToastUtil.showTip("你无法进行语音输入");
                        if (!isKeyUp) {

                        }
                        break;
                    case UdpManager.KEY_VOICE_RESPONSE_FINISH:
                        LogUtil.iii("已经通知服务端停止");
                        //ToastUtil.showTip("已经通知服务器停止");
                        break;
                    case UdpManager.KEY_LANGUAGE_CHANGED:
                        LogUtil.iii("已经通知服务端改变语言");
                        ToastUtil.showTip("输入语音已经改变");
                        break;
                    case UdpManager.KEY_HANDLER_MEETING_CLOSED:
                        new AlertDialog.Builder(RecordActivity.this).setTitle("会议已经关闭，点击确定退出页面").setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                wifiBinder.stopGroup();
                                RecordActivity.this.finish();
                            }
                        }).setCancelable(false).show();
                        break;
                    case UdpManager.KEY_HANDLER_MEETING_DISCONNECTED:
                        new AlertDialog.Builder(RecordActivity.this).setTitle("会议已经失去连接").setPositiveButton("离开", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                wifiBinder.stopGroup();
                                RecordActivity.this.finish();
                            }
                        }).setNegativeButton("等待", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).setCancelable(false).show();
                        break;
                    default:
                        break;
                }
            }
        }
    };

    /**
     * 显示聊天记录
     */
    private void showHistory() {
        chatList.clear();
        ContentResolverUtil resolverUtil = new ContentResolverUtil(this);
        chatList.clear();
        chatList.addAll(resolverUtil.findHistoryById(String.valueOf(wifiBinder.getMeetingInfo().getSerial())));
        mAdapter.notifyDataSetChanged();
        mListView.setSelection(mAdapter.getCount() - 1);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.record_tv_language_cancel:
                record_rl_language_cancel.setVisibility(View.GONE);
                record_ll_language.setVisibility(View.GONE);
                record_fl_cover.setVisibility(View.GONE);
                break;
            case R.id.record_tv_language_en:
                if (wifiBinder != null) {
                    isCH2EN = (false);
                    wifiBinder.changeLocalLanguage(false);
                    wifiBinder.changeServerLanguage(isCH2EN ? 'c' : 'e');
                }
                record_rl_language_cancel.setVisibility(View.GONE);
                record_ll_language.setVisibility(View.GONE);
                record_fl_cover.setVisibility(View.GONE);
                break;
            case R.id.record_tv_language_ch:
                if (wifiBinder != null) {
                    isCH2EN = (true);
                    wifiBinder.changeLocalLanguage(true);
                    wifiBinder.changeServerLanguage(isCH2EN ? 'c' : 'e');
                }
                record_rl_language_cancel.setVisibility(View.GONE);
                record_ll_language.setVisibility(View.GONE);
                record_fl_cover.setVisibility(View.GONE);
        }
    }

    private int currentChoice;

    private void ShowLanguageSwitchDialog() {

        currentChoice = isCH2EN ? 0 : 1;

        new AlertDialog.Builder(this)
                .setTitle("请选择您输入的语言")
                .setSingleChoiceItems(new String[]{"中文", "English"}, currentChoice, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        currentChoice = which;
                    }
                })
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        if (wifiBinder != null) {
                            isCH2EN = (currentChoice == 0);
                            wifiBinder.changeLocalLanguage(isCH2EN);
                            wifiBinder.changeServerLanguage(isCH2EN ? 'c' : 'e');
                        }
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                }).show();
    }

    /**
     * 发送数据到server端
     */
    private void sendVoice(final VoiceInfo voiceInfo) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                wifiBinder.sendVoiceData(voiceInfo);
            }
        }).start();
    }

    /**
     * 状态
     */
    private interface StateImp {

        void invite();

        void getParticipants();

        void setLanguage();

        void setMeeting();

        void collectMeeting();

        void closeMeeting();
    }

    private class CreatorState implements StateImp {


        @Override
        public void invite() {

        }

        @Override
        public void getParticipants() {
            Intent intent = new Intent(RecordActivity.this, DeviceActivity.class);
            intent.putExtra(Constants.ACTIVITY_INTENT_ACTION, Constants.ACTIVITY_ACTION_CREATOR);
            startActivity(intent);
        }

        @Override
        public void setLanguage() {
            //ShowLanguageSwitchDialog();
            record_rl_language_cancel.setVisibility(View.VISIBLE);
            record_ll_language.setVisibility(View.VISIBLE);
            record_fl_cover.setVisibility(View.VISIBLE);
        }

        @Override
        public void setMeeting() {
            Intent intent = new Intent(RecordActivity.this, MeetingGuideActivity.class);
            intent.putExtra(Constants.ACTIVITY_INTENT_ACTION, Constants.ACTIVITY_ACTION_RESETOR);
            startActivity(intent);
        }

        @Override
        public void collectMeeting() {

        }

        @Override
        public void closeMeeting() {
            showLeaveDialog();
        }
    }

    private class ParticipantState implements StateImp {


        @Override
        public void invite() {

        }

        @Override
        public void getParticipants() {
            Intent intent = new Intent(RecordActivity.this, DeviceActivity.class);
            intent.putExtra(Constants.ACTIVITY_INTENT_ACTION, Constants.ACTIVITY_ACTION_PARTICIPANT);
            startActivity(intent);
        }

        @Override
        public void setLanguage() {
            //ShowLanguageSwitchDialog();
            record_rl_language_cancel.setVisibility(View.VISIBLE);
            record_ll_language.setVisibility(View.VISIBLE);
            record_fl_cover.setVisibility(View.VISIBLE);
        }

        @Override
        public void setMeeting() {
            //ToastUtil.showTip("很抱歉，参会人员无法设置会议");
            Intent intent = new Intent(RecordActivity.this, MeetingGuideActivity.class);
            intent.putExtra(Constants.ACTIVITY_INTENT_ACTION, Constants.ACTIVITY_ACTION_RESETOR);
            startActivity(intent);
        }

        @Override
        public void collectMeeting() {

        }

        @Override
        public void closeMeeting() {
            showLeaveDialog();
            //RecordActivity.this.finish();
        }
    }

    private Dialog recoDialog;

    /**
     * 语音输入的提示框
     */
    @SuppressLint("InflateParams")
    private void showLeaveDialog() {
        if (recoDialog == null) {
            recoDialog = UIHelper.getCircularCornerDialog(this);
            Button recoNegButton = (Button) recoDialog.findViewById(R.id.dialog_btn_neg);
            Button recoPosButton = (Button) recoDialog.findViewById(R.id.dialog_btn_pos);
            recoNegButton.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    //语音识别取消
                    if (recoDialog.isShowing()) {
                        recoDialog.cancel();
                    }
                }
            });
            recoPosButton.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    //语音识别完成
                    if (recoDialog.isShowing()) {
                        recoDialog.cancel();
                    }
                    wifiBinder.stopGroup();
                    RecordActivity.this.finish();
                    /*if (mWifiBinder != null) {
                        mWifiBinder.closeMeeting();
                    }*/
                    RecordActivity.this.finish();
                }
            });

            recoDialog = UIHelper.setCircularCornerDialogContent(recoDialog, getString(R.string.action_meeting_close), getString(R.string.action_meeting_yes), getString(R.string.action_meeting_no));
            recoDialog.setCanceledOnTouchOutside(false);
            recoDialog.setCancelable(false);
        }

        recoDialog.show();
    }

    @Override
    public void onBackPressed() {

    }
}
